package com.usvisatrack.services;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.usvisatrack.core.dao.model.UscisCase;
import com.usvisatrack.core.dao.model.VisaClass;
import com.usvisatrack.core.factories.UscisCaseFactory;
import com.usvisatrack.services.common.DataCrawl;

/**
 * MerchandiseDataImporter to read folder in disk and import to DB
 * 
 * @author YuCheng Hu
 *
 */
public class UscisCaseImporter extends DataCrawl {
	private static final Logger logger = LoggerFactory.getLogger(UscisCaseImporter.class);

	private final static String URL_USCIS_CASE = "https://egov.uscis.gov/casestatus/mycasestatus.do?appReceiptNum=";

	private static List<String> caseNumberList = new ArrayList<>();

	public static HashMap<String, VisaClass> visaClassMap = new HashMap<String, VisaClass>();

	/**
	 * Command process function
	 */
	@Override
	public void parseCommandLine(String[] args) {
		options.addOption("l", true, "Clean all agents input information");
		options.addOption("h", true, "Clean one agent by input email address");

		CommandLineParser parser = new DefaultParser();

		// parse command line
		try {
			CommandLine cmd = parser.parse(options, args);

			if (cmd.hasOption("s")) {
				// this.minId = Integer.parseInt(cmd.getOptionValue("l"));
				// this.maxId = Integer.parseInt(cmd.getOptionValue("h"));
			}

		} catch (Exception e) {
			logger.warn("CLI Parse failed, using default timestamp", e);
		}
	}

	/**
	 * Run Function
	 */
	@Override
	public void run() {
		initData(); // Init data from database

		for (String caseNumber : caseNumberList) {
			crawlUscisCase(URL_USCIS_CASE + caseNumber);
		}
	}

	/**
	 * crawlWebItem by parse web page
	 */
	private void crawlUscisCase(String cURL) {
		logger.debug("Crawl USCIS Web Data to load Case info.");

		Document doc = null;

		try {
			doc = Jsoup.connect(cURL).get();

			// CASE NUMBER
			String caseNumber = StringUtils.upperCase(StringUtils.substringAfterLast(cURL, "appReceiptNum="));

			// CASE STATUS
			String caseStatus = StringUtils.trimToNull(doc.select("h1").get(0).text());

			// CASE DATE
			String[] caseContentArray = StringUtils.split(doc.select("p").get(0).text(), ",");
			DateTime dt = null;
			if (StringUtils.startsWithIgnoreCase(caseContentArray[0], "On")) {
				String caseDate = StringUtils.trim(StringUtils.substringAfter(caseContentArray[0], "On"));
				caseDate = caseDate + "," + StringUtils.trim(caseContentArray[1]);
				dt = DateTimeFormat.forPattern("MMMMM dd,yyyy").parseDateTime(caseDate);
			}

			// CASE FORM
			String uscisFormCode = StringUtils.trim(StringUtils.substringAfter(caseContentArray[2], "Form"));

			logger.debug("Case Number / Form / Date - [{}]/[{}]/[{}]", caseNumber, uscisFormCode, dt);

			UscisCase uscisCase = new UscisCase();
			uscisCase.setUscisCaseNumber(caseNumber);
			uscisCase.setUscisCaseStatus(UscisCaseFactory.getUscisCaseStatusByCode(StringUtils.capitalize(caseStatus)));
			uscisCase.setUscisForm(UscisCaseFactory.getUscisFormByCode(uscisFormCode));
			if (uscisCase.getUscisForm() == null) {
				uscisCase.setUscisForm(UscisCaseFactory.getUscisFormByCode("UNKNOW"));
			}

			if (dt != null) {
				if (uscisCase.getUscisCaseStatus().getId() != 1000 && uscisCase.getUscisCaseStatus().getId() != 1001) {
					uscisCase.setDateUscisCaseUpdated(dt.toDate());
				} else {
					uscisCase.setDateUscisCaseReceived(dt.toDate());
				}
			}

			UscisCaseFactory.save(uscisCase);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 
	 */
	private void initData() {
		logger.error("Init Data from Database");
		String caseNumber = "SRC1790472682";

		String preCaseNumber = StringUtils.left(caseNumber, 8);
		long ascCaseNumberDigital = NumberUtils.createLong(StringUtils.right(caseNumber, 5));
		long descCaseNumberDigital = NumberUtils.createLong(StringUtils.right(caseNumber, 5));

		// ASC
		int i = 0;
//		do {
//			ascCaseNumberDigital = ascCaseNumberDigital + 1;
//			String newCaseNumber = StringUtils.upperCase(preCaseNumber + Long.toString(ascCaseNumberDigital));
//			UscisCase uscisCase = UscisCaseFactory.getUscisCaseByCaseNumber(newCaseNumber);
//			if (uscisCase == null) {
//				caseNumberList.add(newCaseNumber);
//				i++;
//			} else {
//				if (Days.daysBetween(new DateTime(), new DateTime(uscisCase.getModifyDate())).getDays() > 3) {
//					caseNumberList.add(newCaseNumber);
//					i++;
//				}
//			}
//		} while (i <= 100);

		// DESC
		i = 0;
		do {
			descCaseNumberDigital = descCaseNumberDigital - 1;
			String newCaseNumber = StringUtils.upperCase(preCaseNumber + Long.toString(descCaseNumberDigital));
			UscisCase uscisCase = UscisCaseFactory.getUscisCaseByCaseNumber(newCaseNumber);
			if (uscisCase == null) {
				caseNumberList.add(newCaseNumber);
				i++;
			} else {
				if (Days.daysBetween(new DateTime(), new DateTime(uscisCase.getModifyDate())).getDays() > 3) {
					caseNumberList.add(newCaseNumber);
					i++;
				}
			}
		} while (i <= 1000);

		logger.debug("caseNumberList Size - [{}]", caseNumberList.size());
	}
}
